package com.gzc.just.play.last.war.common.share.data;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.io.Serializable;
import java.util.List;
import java.util.Optional;

/**
 * 统一数据访问服务接口
 * 为All-in-One开发模式提供统一的数据访问抽象层
 * 支持MySQL和SQLite双实现
 */
public interface DataAccessService {
    
    /**
     * 根据ID查找实体
     */
    <T, ID extends Serializable> Optional<T> findById(Class<T> entityClass, ID id);
    
    /**
     * 保存实体
     */
    <T> T save(T entity);
    
    /**
     * 批量保存实体
     */
    <T> List<T> saveAll(Iterable<T> entities);
    
    /**
     * 删除实体
     */
    <T> void delete(T entity);
    
    /**
     * 根据ID删除实体
     */
    <ID extends Serializable> void deleteById(Class<?> entityClass, ID id);
    
    /**
     * 查询所有实体
     */
    <T> List<T> findAll(Class<T> entityClass);
    
    /**
     * 分页查询所有实体
     */
    <T> Page<T> findAll(Class<T> entityClass, Pageable pageable);
    
    /**
     * 根据ID列表查询实体
     */
    <T, ID extends Serializable> List<T> findAllById(Class<T> entityClass, Iterable<ID> ids);
    
    /**
     * 判断实体是否存在
     */
    <T, ID extends Serializable> boolean existsById(Class<T> entityClass, ID id);
    
    /**
     * 统计实体数量
     */
    <T> long count(Class<T> entityClass);
    
    /**
     * 执行自定义查询
     */
    <T> List<T> executeQuery(String query, Class<T> resultClass, Object... params);
    
    /**
     * 执行自定义更新
     */
    int executeUpdate(String updateQuery, Object... params);
    
    /**
     * 开启事务
     */
    void beginTransaction();
    
    /**
     * 提交事务
     */
    void commitTransaction();
    
    /**
     * 回滚事务
     */
    void rollbackTransaction();
    
    /**
     * 在事务中执行操作
     */
    <T> T executeInTransaction(TransactionalOperation<T> operation);
    
    /**
     * 获取数据库类型
     */
    DatabaseType getDatabaseType();
    
    /**
     * 事务操作接口
     */
    @FunctionalInterface
    interface TransactionalOperation<T> {
        T execute();
    }
    
    /**
     * 数据库类型枚举
     */
    enum DatabaseType {
        MYSQL("MySQL"),
        SQLITE("SQLite");
        
        private final String name;
        
        DatabaseType(String name) {
            this.name = name;
        }
        
        public String getName() {
            return name;
        }
    }
}